# encoding: utf-8
require 'uri'
require 'pty'
require 'expect'

module Git
  # 根据项目名获取该项目wiki在linux的名称
  # =》 test_project， test_project.wiki
  # 或根据wiki页面名，获取linux下文件名
  # =>index, index.md
  def git_wiki_linux_name(name, type='project')
    case type
      when 'page'
        "#{name}.md"
      else
        "#{name}.wiki"
    end
  end

  # 获取项目git地址
  def git_ssh_url(username, project_name, type = 'ssh', is_wiki = false)
    web_host = URI.parse($config['web_url']).host
    linux_project_name = is_wiki ? git_wiki_linux_name(project_name): project_name

    case type
      when 'https'
        return 'https://'+web_host+'/'+username+'/'+linux_project_name+'.git'
      when 'git'
        return 'git://'+web_host+'/'+username+'/'+linux_project_name+'.git'
      else
        return 'git@'+web_host+':'+username+'/'+linux_project_name+'.git'
    end
  end

  # git clone
  # user => 执行clone操作的用户信息
  # project_user => 项目的用户名
  # @return [true/false]
  def git_clone(user, project_user, project, type = 'ssh', is_wiki = false)
    liunx_username = user['liunx_username']
    linux_password = user['linux_password']
    web_login_username = user['login_username']
    web_login_password = user['login_password']

    project_username = get_hash(project_user, 'username')
    project_name = get_hash(project, 'project_name')

    # 获取git地址
    ssh_url = git_ssh_url(project_username, project_name, type, is_wiki)

    # 获取仓库名称
    linux_project_name = is_wiki ? git_wiki_linux_name(project_name) : project_name

    # git 命令
    git_command = "git clone #{ssh_url}"

    ruby_git_script(liunx_username, linux_password, linux_project_name, git_command, web_login_username, web_login_password, 'clone')

    # 验证clone是否成功
    FileTest::exist?("/home/#{liunx_username}/#{linux_project_name}")
  end

  # git push
  # @return [无返回值]
  def git_push(user, project, branch = 'master', is_wiki = false)
    liunx_username = user['liunx_username']
    linux_password = user['linux_password']
    web_login_username = user['login_username']
    web_login_password = user['login_password']
    project_name = get_hash(project, 'project_name')

    # 获取仓库名称
    linux_project_name = is_wiki ? git_wiki_linux_name(project_name) : project_name

    # git 命令
    git_command = "git push origin #{branch}"

    ruby_git_script(liunx_username, linux_password, linux_project_name, git_command, web_login_username, web_login_password, 'push')
    sleep 2
  end

  # git add
  # @return [无返回值]
  def git_add(user, project, times = 1)
    i = 0
    while i < times
        time = Time.now.to_i
        filename = time.to_s+"_#{i}"
        git_add_designation(user, project, filename)
        i = i+1
    end
  end

  # 添加指定名称、指定内容的文件
  # @return [0是正确，其他错误]
  def git_add_designation(user, project, filename, content = '', is_wiki = false)
    linux_username = user['liunx_username']
    linux_password = user['linux_password']
    project_name = get_hash(project, 'project_name')

    if content.empty? then
      content = "'#{user['nickname']} add designation content to #{filename}, current time #{Time.now}'"
    end

    # 获取仓库名称
    linux_project_name = is_wiki ? git_wiki_linux_name(project_name) : project_name

    ruby_git_add_script(linux_username, linux_password, linux_project_name, filename, content)
  end

  # 验证git操作是否成功
  def verify_git_operate
      status = 1
      filename = '/tmp/git_exec_status.txt'
      if FileTest::exist?(filename) then
          status = File.readlines(filename)
      end

      system("echo 9 > #{filename}")

      status.first.to_i
  end

  # 创建并选择该分支
  # @return [0是正确，其他错误]
  def git_create_branch(user, project, branch)
    liunx_username = user['liunx_username']
    linux_password = user['linux_password']
    project_name = get_hash(project, 'project_name')
    command = "git checkout -b #{branch}"

    ruby_git_current(liunx_username, linux_password, project_name, command)
  end

  # 分支的创建及选择
  # @return [0是正确，其他错误]
  def git_checkout(user, project, branch_name, is_new = false)
    liunx_username = user['liunx_username']
    linux_password = user['linux_password']
    project_name = project['project_name']

    if is_new then
      command = "git checkout -b #{branch_name}"
    else
      command = "git checkout #{branch_name}"
    end

    ruby_git_current(liunx_username, linux_password, project_name, command)
  end

  # 远程拉取项目
  # @return [0是正确，其他错误]
  def git_pull(user, project, project_user, branch = 'master')
    liunx_username = user['liunx_username']
    linux_password = user['linux_password']
    project_name = project['project_name']
    project_username = project_user['username']

    pull_url = git_ssh_url(project_username, project_name)

    command = "git pull #{pull_url} #{branch}"

    ruby_git_current(liunx_username, linux_password, project_name, command)
  end

  # 合并分支到当前所在分支
  # @return [0是正确，其他错误]
  def git_merge(user, project, branch)
    liunx_username = user['liunx_username']
    linux_password = user['linux_password']
    project_name = project['project_name']

    command = "git merge #{branch}"

    ruby_git_current(liunx_username, linux_password, project_name, command)
  end

  # 删除分支（本地、远程）
  # @return [0是正确，其他错误]
  def delete_branch(user, project, branch_name, is_remote = true)
    liunx_username = user['liunx_username']
    linux_password = user['linux_password']
    project_name = project['project_name']

    if is_remote
      command = "git push origin :#{branch_name}"
    else
      command = "git branch -D #{branch_name}"
    end

    ruby_git_current(liunx_username, linux_password, project_name, command)
  end

  # clone\push 脚本
  def ruby_git_script(linux_user, linux_pass, project_name, command, web_user, web_pass, type)
    PTY.spawn("su #{linux_user}") do |r_f,w_f,pid|
      r_f.expect('assword: ', 1) do
        w_f.puts "#{linux_pass}"
      end
      r_f.expect('密码', 1) do
        w_f.puts "#{linux_pass}"
      end

      r_f.expect('$', 1) do
        if (type == 'clone') then
          w_f.puts "cd ~"
          sleep 1
          w_f.puts "rm -rf  #{project_name}"
        else
          w_f.puts "cd ~/#{project_name}"
        end

        sleep 1
        w_f.puts "#{command}"
        sleep 1
      end

      r_f.expect('Username for', 1) do
        w_f.puts "#{web_user}"
        sleep 1
      end
      r_f.expect('Password for', 1) do
        w_f.puts "#{web_pass}"
        sleep 1
      end

      begin
        w_f.puts "quit"
      rescue
      end
    end
  end

  # 添加文件脚本
  def ruby_git_add_script(linux_user, linux_pass, project_name, filename, content)
    PTY.spawn("su #{linux_user}") do |r_f,w_f,pid|
      r_f.expect('assword: ', 1) do
        w_f.puts "#{linux_pass}"
      end
      r_f.expect('密码', 1) do
        w_f.puts "#{linux_pass}"
      end

      r_f.expect('$', 1) do
        w_f.puts "cd ~/#{project_name}"
        sleep 1
        w_f.puts "echo #{content} > #{filename}"
        sleep 1
        w_f.puts "git add ."
        sleep 1
        w_f.puts "git commit -m 'add #{filename}'"
        sleep 1
      end

      begin
        w_f.puts "quit"
      rescue
      end
    end
  end

  # 通用脚本
  def ruby_git_current(linux_user, linux_pass, project_name, command)
    PTY.spawn("su #{linux_user}") do |r_f,w_f,pid|
      r_f.expect('assword: ', 1) do
        w_f.puts "#{linux_pass}"
      end
      r_f.expect('密码', 1) do
        w_f.puts "#{linux_pass}"
      end

      r_f.expect('$', 1) do
        w_f.puts "cd ~/#{project_name}"
        sleep 1
        w_f.puts "#{command}"
        sleep 1
      end

      begin
        w_f.puts "quit"
      rescue
      end
    end

  end

end